//-------------------------------------------------------------------------
// File: Registry.cpp
//
// Descr.: - todo -
//
// Author: Stefan Leihkauf
// Date:   8/9/2011
//-------------------------------------------------------------------------
#include "cb_pch.h"
#include "registry/Registry.h"
#include <boost/algorithm/string.hpp>

const StdString Registry::PathDelimiter = _T("\\");

//-------------------------------------------------------------------------
/**
	@param rootKeyHandle - one of the predefined Windows rootkey handles

	@return pointer to opened registry key if successfull or an empty pointer otherwise
*/
RegistryKey Registry::OpenRootKey(const RootKeyHandle& rootKeyHandle, const RegistryKey::AccessRights& accessRights /*= RegistryKey::Read*/)
{
	WinHKey handle;
	HKEY hkey = 0;

	/* as documentation suggests we call a different API if opening HKEY_CURRENT_USER for the case the current thread is
	   impersonating a different user
	*/
	if(rootKeyHandle == HCurrentUser) {
		if(ERROR_SUCCESS == RegOpenCurrentUser(accessRights.to_ulong(), &hkey))
			handle.reset(hkey);
	} else {
		if(ERROR_SUCCESS == RegOpenKeyEx(rootKeyHandle, 0, 0, accessRights.to_ulong(), &hkey)) {
			handle.reset(hkey);
		}
	}

	return RegistryKey(handle, rootKeyHandle.toString());
}

//-------------------------------------------------------------------------
/**
*/
RegistryKey Registry::ClassesRoot()
{
	return Registry::OpenRootKey(HClassesRoot);
}
//-------------------------------------------------------------------------
/**
*/
RegistryKey Registry::CurrentConfig()
{
	return Registry::OpenRootKey(HCurrentConfig);
}

//-------------------------------------------------------------------------
/**
*/
RegistryKey Registry::CurrentUser()
{
	return Registry::OpenRootKey(HCurrentUser);
}

//-------------------------------------------------------------------------
/**
*/
RegistryKey Registry::LocalMachine()
{
	return Registry::OpenRootKey(HLocalMachine);
}

//-------------------------------------------------------------------------
/**
*/
RegistryKey Registry::Users()
{
	return Registry::OpenRootKey(HUsers);
}

//-------------------------------------------------------------------------
/**
*/
RegistryKey Registry::OpenKey(const RootKeyHandle& rootKeyHandle, const StdString& pathName, const RegistryKey::AccessRights& accessRights)
{
	WinHKey handle;
	HKEY hkey = 0;
	StdString name;

	if(ERROR_SUCCESS == RegOpenKeyEx(rootKeyHandle, pathName.c_str(), 0, accessRights.to_ulong(), &hkey)) {
		// strip path from name
		std::vector<StdString> strs;
		boost::split(strs, pathName, boost::is_any_of(Registry::PathDelimiter));

		handle.reset(hkey);
	}

	return RegistryKey(handle, name);
}